﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HAMath;

namespace HA.Data
{
    public static class IDWScatter2D
    {
        /// <summary>
        /// 根据离散点坐标和浓度值用反距离平方法对网格进行插值
        /// </summary>
        /// <param name="pts"></param>
        /// <param name="values"></param>
        /// <param name="grid"></param>
        /// <param name="isUseAll">是否使用全部网格点进行插值计算</param>
        /// <param name="effectiveDis">如果不是使用全部点，则使用有效距离内的点</param>
        /// <returns></returns>
        public static List<double> Interpolation(List<HAMath.Point2D> pts, List<double> values, List<HAMath.Point2D> grid ,bool isUseAll,int num)
        {
            if (pts == null || pts.Count == 0) return null;
            if (values == null || values.Count == 0) return null;
            if (grid == null || grid.Count == 0) return null;
            
            List<double> result = new List<double>();

            if (isUseAll == true) //使用全部数据进行插值
            {
                foreach (HAMath.Point2D pt in grid)
                {
                    double value = HAMath.InverseDistance.InverseDistanceWeight2D.GetPointElevation(pt, pts, values);
                    result.Add(value);
                }
            }
            else
            {
                foreach (HAMath.Point2D gridPt in grid)
                {
                    List<HAMath.Point2D> usefulPts = new List<HAMath.Point2D>();
                    List<double> usefulValues = new List<double>();

                    double min = double.MaxValue;                   

                    for (int n = 0; n < 16; n++)
                    {
                        HAMath.Point2D temPt = new HAMath.Point2D();
                        double temValue=0;

                        for (int i = 0; i < pts.Count; i++)
                        {
                            double distance = Math.Sqrt((gridPt.X - pts[i].X) * (gridPt.X - pts[i].X) + (gridPt.Y - pts[i].Y) * (gridPt.Y - pts[i].Y));

                            if (distance < min && usefulPts .Contains (pts[i])==false ) 
                            {
                                min = distance;
                                temPt = pts[i];
                                temValue = values[i]; 
                            }
                        }
                        usefulPts.Add(temPt);
                        usefulValues.Add(temValue);
                    }

                    double value;
                    if (usefulPts.Count > 0)
                    {
                        value = HAMath.InverseDistance.InverseDistanceWeight2D.GetPointElevation(gridPt, usefulPts, usefulValues);
                    }
                    else
                    {
                        value = HAMath.InverseDistance.InverseDistanceWeight2D.GetPointElevation(gridPt, pts, values);
                    }
                    result.Add(value);
                }

            }

            return result;

        }


        /// <summary>
        /// 插值需要考虑多种因素
        /// </summary>
        /// <param name="spts"></param>
        /// <param name="grid"></param>
        /// <param name="option"></param>
        /// <returns></returns>
        public static double[] Interoplation(List<DSSPoint> spts, List<HAMath.Point2D> grid, InterOption2D option2D)
        {


            IDWOption option=option2D.IdwOption;




            double[] c=new double[grid.Count];


            alglib.idwinterpolant idw = new alglib.idwinterpolant();

            int n=spts.Count;

            int nx=2; //2维度插值





            double[,] xy = new double[n, nx + 1];

            int i=0;

            foreach (DSSPoint pt in spts)
            {

                xy[i, 0] = pt.X;
                xy[i, 1] = pt.Y;

                xy[i, 2] = pt.Value;

                i++;
               
            }



           alglib.idwbuildmodifiedshepard(xy,n,nx,option.NodalFunction,option.Nq,option.Nw,out idw);


            int m=0;


           foreach (Point2D pt in grid)
           {
              c[m]= alglib.idwcalc(idw,new double[]{pt.X,pt.Y});

              m++;
           }



            //根据插值选项的要求进行特殊的处理






            return c;

 
        }



    }
}
